Week 6

For this week i wanted to try and read data from tilt sensor and later send data with esp32 to client, connected over the wi-fi. The esp32 will act as access point, so there will be no need for connecting to any external router. So it would work anywhere.

I also wanted to make touch sensor using copper pads and arduino. I will cover this first.
When i started i did not know, how to approach building this touchpad i only knew, it could be done. I tested few different configurations and here i discovered first problem. Analog pins used for reading are very sensitive. When reading from pin not connected to annything, it picked up on the interference of main power grid. The copper pad made it even worse working as antenna. Here is how it looked:

As a solution i connected the pad with 470k-ohm pull-up resistor to 5V. It looked much better, interference now took only 3 or so values out of 1023 possible. Here it is with pull-up resistor:

Now i needed to figure out, when and where was the touchpad being touched. All columns are connected by pull-up resistors to 5V. When you connect column connected to 5V and row connected to GND, using finger, it is now connected and voltage drop on column pin can be measured. Here is how it looks when connecting row and column using finger:

This is how the touchpad was connected in the end. The cappacitors represent the copper pads.

Now i needed to automate the process for checking all rows and columns. The rows are one by one either connected to ground or left floating and with each row switch all columns are read, so in total 16 reading for one update. This can be done very fast.The code on arduino side is very simple.

                
#define TOUCH_THRESHOLD  750

void setup() {
    Serial.begin(112500);
    for(uint8_t pin = 2; pin <= 5; ++pin){
    // SET digital pins in floating state
    pinMode(pin, INPUT);
    }
    for(uint8_t pin = A4; pin <= A7; ++pin){
    // SET analog pins as input (FLOATING)
    pinMode(pin, INPUT);
    }
}

void loop() {
    sense_touch();
    delay(100);
}


void sense_touch(){
    // PINS D2-D5 === numbers 2 - 5 -- SETTING TO LOW OR FLOATING
    // PINS A4 - A7 === numbers 18 - 21 -- READING ANALOG VALUE

    for(uint8_t out_pin = 2; out_pin <= 5; ++out_pin){
    pinMode(out_pin, OUTPUT);
    digitalWrite(out_pin, LOW);
    delayMicroseconds(10);
    Serial.print("p");
    for(uint8_t in_pin = A4; in_pin <= A7; ++in_pin){
        uint8_t result = check_for_touch(in_pin);
        Serial.print(result);
    }
    pinMode(out_pin, INPUT); // Set back to floating
    }
    Serial.println("");

}

uint8_t check_for_touch(uint8_t pin){
    if(analogRead(pin) < TOUCH_THRESHOLD) return true;
    else return false;
}
                
            

Last thing to do was to write computer side program, that can read, interpret and show measured data. I chose python for this task. The code on computer side is a bit longer and harder than the arduino side, but most of it is, making the visual side look nice. Here are main parts of the code:

            
###--------------OBJECT FOR DRAWING POINT TOUCHED-------------------------
class Interpolate(object):
def __init__(self, interpolation_steps, touchpad_rect, ignore_zero_pos):
    self.current_pos = None
    self.prev_pos = None
    self.i_steps = interpolation_steps
    self.i_index = 0  
    self.touchpad_rect = touchpad_rect
    self.ignore_limit = ignore_zero_pos
    self.ignore_cnt = 0
    self.trail = []
    self.trail_cnt = 5
    self.trail_index = 0

def update_pos(self, new_pos):
    if new_pos is not None:
        self.prev_pos = self.current_pos
        self.current_pos = new_pos
        self.i_index = 0
        self.ignore_cnt = 0
    else:
        if self.ignore_cnt < self.ignore_limit:
            self.ignore_cnt += 1
            self.prev_pos = None
        else:
            self.prev_pos = self.current_pos
            self.current_pos = new_pos
            self.i_index = 0
            self.ignore_cnt = 0
            
        
def get_inter_pos(self):
    if self.current_pos and self.prev_pos:
        dx = (self.current_pos[0] - self.prev_pos[0]) / (self.i_steps + 1)
        dy = (self.current_pos[1] - self.prev_pos[1]) / (self.i_steps + 1)
        x = self.prev_pos[0] + dx*self.i_index
        y = self.prev_pos[1] + dy*self.i_index
        self.i_index += 1
        for i in range(self.trail_cnt):
            self.trail.append([x - (dx/3) * i, y - (dy/3) * i])
        return x, y
    elif self.current_pos:
        return self.current_pos
    else:
        return None, None
    
def update(self, win):
    x, y = self.get_inter_pos()
    
    win.fill((40, 40, 40))
    # draw bounding box
    pygame.draw.rect(win, (255, 255, 255), self.touchpad_rect, 3)
    if x:
        pygame.draw.circle(win, (255, 255, 255), (x, y), 5)
        if len(self.trail) > 0:
            for i in range(self.trail_cnt):
                pygame.draw.circle(win, (255, 255, 255), self.trail[i], 5 - i)
            self.trail = []
    pygame.display.flip()
                    
                
###----------------MAIN LOOP------------------------------------

clock = pygame.time.Clock()
anim_inter = Interpolate(ANIM_FPS/DATA_FPS, touchpad_rect, IGNORE_ZERO_POS)
while run:
    clock.tick(ANIM_FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
            
    if serial_obj.in_waiting:
        data = serial_obj.readline()
        data_decoded = None
        try:
            data_decoded = data.decode('utf')
        except UnicodeDecodeError:
            print("Error in accepting data")
        if data_decoded:
            data = data_decoded.strip().split("p")
            print(data)
            x, y = calculate_point(data[1:])
            if x:
                anim_inter.update_pos([x, y])
            else:
                anim_inter.update_pos(None)
    serial_obj.read_all()
    anim_inter.update(win)
            
        

As a last thing i designed and 3D printed box for the arduino and wires.

Here is the final product:

The second thing i made this week was a website, that accepted randomly generated data from esp32 and showed them on screen using html. Here is how it looked:

←Back